package com.yznote.compileserver.yCompile.execute;

import com.yznote.compileserver.yCompile.process.ProcessManage;
import com.yznote.compileserver.yCompile.result.YResult;
import com.yznote.compileserver.yCompile.result.YResultType;
import com.yznote.compileserver.yCompile.runtime.CmdExecutor;
import com.yznote.compileserver.yCompile.runtime.CmdLib;
import com.yznote.compileserver.yCompile.runtime.CmdParam;
import com.yznote.compileserver.yCompile.type.CodeType;
import com.yznote.compileserver.yCompile.io.YInput;
import com.yznote.compileserver.yCompile.io.YOutPut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.FileOutputStream;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 编译型语言
 */
@Component
public class CompileExecutor extends PlateFormExecutor {
    @Autowired
    Runtime runtime;
    @Autowired
    CmdExecutor cmdExecutor;
    @Override
    public void execute(YInput yInput,YOutPut yOutPut, CodeType type, String path, String fName) throws Exception{
        // 读取源代码
        byte[] data = new byte[1024*1024];
        int len = yInput.read(data);
        // 将字节数组写入本地文件 进行编译和运行 根据type进行存储
        yInput.close();
        FileOutputStream fileOutputStream = new FileOutputStream(path);
        fileOutputStream.write(data,0,len);
        fileOutputStream.close();
        // 启动进程
        Process process = cmdExecutor.execute(runtime,"F:\\", CmdLib.JAVAC,fName);
        // 获取进程管理器
        ProcessManage processManage = new ProcessManage(process);
        // 等待编译结束
        long compileTime = processManage.trywait(1000, TimeUnit.MILLISECONDS);
        // 获取编译结果
        String s = processManage.readError();
        if(s!=null&&s.trim().length()!=0){
         yOutPut.writeType(YResultType.COMPILE_ERROR);
         yOutPut.writeTimes(compileTime);
         yOutPut.writeOut(s);
         processManage.closeAllStream();
         processManage.kill();
         return;
        }
        // 如果没有错误 关闭编译进程的流文件 开始运行class文件
        processManage.closeAllStream();
        processManage.kill();
        process = cmdExecutor.execute(runtime,"F:\\",CmdLib.JAVA,fName.split("\\.")[0]);
        ProcessManage processManage1 = new ProcessManage(process);
        // 开始监控运行线程
        long times1 = 0;
        try {
            times1 = processManage1.trywait(1000, TimeUnit.MILLISECONDS);
        }catch (Exception e){
            // 超时
            processManage1.closeAllStream();
            processManage1.kill();
            yOutPut.writeOut("运行超时");
            yOutPut.writeType(YResultType.RUN_TIMEOUT);
            return;
        }
        // 未超时 进行下一步操作
        String s1 = processManage1.readError();
        if(s1!=null&&s1.trim().length()!=0){
            yOutPut.writeTimes(times1);
            yOutPut.writeType(YResultType.RUN_ERROR);
            yOutPut.writeOut(s1);
            processManage1.closeAllStream();
            processManage1.kill();
            return;
        }
        String s2 = processManage1.readAll();
        yOutPut.writeTimes(times1);
        yOutPut.writeType(YResultType.RUN_SUCCESS);
        yOutPut.writeOut(s2);
        processManage1.closeAllStream();
        processManage1.kill();
        return;
    }
}
